package com.live.stamp.web.user.baseDataService.impl;

import com.hikeSoft.common.utils.BaseUtils;
import com.live.stamp.base.service.impl.BaseSupportServiceImpl;
import com.live.stamp.web.user.baseDataService.UserBaseService;
import com.live.stamp.web.user.model.TUser;
import com.live.stamp.web.user.model.TUserAttention;
import com.live.stamp.web.user.model.TUserFriend;
import com.live.stamp.web.user.model.TUserShield;
import com.live.stamp.web.user.vo.TUserVo;
import org.apache.commons.lang.StringUtils;
import org.apache.commons.lang.exception.ExceptionUtils;
import org.springframework.boot.container.core.common.BusinessException;
import org.springframework.boot.container.core.log.ZKLogger;
import org.springframework.boot.container.core.log.ZKLoggerFactory;
import org.springframework.stereotype.Service;

import java.sql.SQLException;
import java.util.Collections;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

/**
 * @author cwd E-mail: wendong.cao@jsxfedu.com
 * @version 1
 * @date 2018/4/12 16:05
 */
@Service
public class UserBaseServiceImpl extends BaseSupportServiceImpl implements UserBaseService {

    private static final ZKLogger logger = ZKLoggerFactory.getLogger(UserBaseServiceImpl.class);

    @Override
    public TUser getUser(TUserVo tUserVo) throws BusinessException {
        Map<String,Object> params = this.searchParma(tUserVo);
        String sql = "select * from t_user where 1=1 "+params.get("sql");

        try{
            return this.getDao().selectOne(TUser.class,sql,(Map<String, Object>) params.get("paramMap"));
        }catch(Exception e){
            logger.error(e.getMessage());
            throw new BusinessException(e.toString());
        }
    }

    @Override
    public TUser getUserById(String userId) throws BusinessException {
        TUserVo tUserVo = new TUserVo();
        tUserVo.setId(userId);

        return getUser(tUserVo);
    }

    @Override
    public int addShiled(TUserShield tUserShield) throws BusinessException {
        try{
            return this.getDao().insert(tUserShield);
        }catch(Exception e){
            logger.error(e.getMessage(), e);
            throw new BusinessException(e.toString());
        }
    }

    @Override
    public int deleteShiled(TUserShield tUserShield) throws BusinessException {
        try{
            String whereSql = " fromUserId=:fromUserId and toUserId=:toUserId ";
            Map<String, Object> param = new HashMap<>();
            param.put("fromUserId", tUserShield.getFromUserId());
            param.put("toUserId", tUserShield.getToUserId());

            return this.getDao().delete("t_user_shield", whereSql, param);
        }catch(Exception e){
            logger.error(e.getMessage(), e);
            throw new BusinessException(e.toString());
        }
    }

    @Override
    public List<TUserShield> getShields(TUserShield tUserShield) throws BusinessException {
        String sql = "select * from t_user_shield where fromUserId=:fromUserId and toUserId=:toUserId ";
        Map<String, Object> param = new HashMap<>();
        param.put("fromUserId", tUserShield.getFromUserId());
        param.put("toUserId", tUserShield.getToUserId());

        try {
            return this.getDao().selectList(TUserShield.class, sql, param);
        } catch (SQLException e) {
            logger.error(e.getMessage(), e);
            throw new BusinessException(e.toString());
        }
    }

    @Override
    public int addUser(TUser tUser) throws BusinessException {
        try{
            return this.getDao().insert(tUser);
        }catch(Exception e){
            logger.error(e.getMessage(), e);
            throw new BusinessException(e.toString());
        }
    }

    @Override
    public int updateUser(TUserVo tUserVo) throws BusinessException {
        logger.debug("enter into updateUser method. param updateGoods:{}", tUserVo);

        String sql = "UPDATE t_user SET $value$ WHERE ID =:id";
        Map<String, Object> params = new HashMap<>();
        params.put("id", tUserVo.getId());

        String sqlValue = createUpdateUserInfo(params, tUserVo);
        sql = sql.replace("$value$", sqlValue);
        try {
            return this.getDao().exec(sql, params);
        } catch (SQLException e) {
            logger.error(e.getMessage(), e);
            throw new BusinessException("更新失败");
        }
    }

    @Override
    public int addFriend(TUserFriend tUserFriend) throws BusinessException {
        try{
            return this.getDao().insert(tUserFriend);
        }catch(Exception e){
            logger.error(e.getMessage(), e);
            throw new BusinessException(e.toString());
        }
    }

    @Override
    public TUserFriend getUserFriendById(String id) throws BusinessException {
        Map<String,Object> params = new HashMap<>();
        String sql = "select * from t_user_friend where id=:id";
        params.put("id", id);

        try{
            return this.getDao().selectOne(TUserFriend.class,sql,params);
        }catch(Exception e){
            logger.error(ExceptionUtils.getFullStackTrace(e));
            throw new BusinessException(e.toString());
        }
    }

    @Override
    public int deleteFriend(TUserFriend tUserFriend) throws BusinessException {
        Map<String,Object> params = new HashMap<>();
        String sql = "update t_user_friend set state='0' where (tUserIdA=:tUserIdA and tUserIdB=:tUserIdB) or (tUserIdA=:tUserIdB and tUserIdB=:tUserIdA)";
        params.put("tUserIdA", tUserFriend.getTUserIdA());
        params.put("tUserIdB", tUserFriend.getTUserIdB());

        try{
            return this.getDao().exec(sql,params);
        }catch(Exception e){
            logger.error(ExceptionUtils.getFullStackTrace(e));
            throw new BusinessException(e.toString());
        }
    }

    @Override
    public int updateUserFriend(TUserFriend tUserFriend) throws BusinessException {
        logger.debug("enter into updateUserFriend method. param tUserFriend:{}", tUserFriend);

        String sql = "UPDATE t_user_friend SET $value$ WHERE ID =:id";
        Map<String, Object> params = new HashMap<>();
        params.put("id", tUserFriend.getId());

        String sqlValue = createUpdateUserFriendInfo(params, tUserFriend);
        sql = sql.replace("$value$", sqlValue);
        try {
            return this.getDao().exec(sql, params);
        } catch (SQLException e) {
            logger.error(e.getMessage(), e);
            throw new BusinessException("更新失败");
        }
    }

    @Override
    public int shieldUserFriend(TUserVo tUserVo) throws BusinessException {

        String sql = "update t_user_friend set state='4' where ((tUserIdA=:userA and tUserIdB=:userB) or (tUserIdA=:userB and tUserIdB=:userA)) and state!='3'";

        Map<String, Object> params = new HashMap<>();
        params.put("userA", tUserVo.getId());
        params.put("userB", tUserVo.getUserId());

        try{
            return this.getDao().exec(sql, params);
        }catch(Exception e){
            logger.error(e.getMessage(), e);
            throw new BusinessException(e.toString());
        }
    }

    @Override
    public int addAttention(TUserAttention tUserAttention) throws BusinessException {
        try{
            return this.getDao().insert(tUserAttention);
        }catch(Exception e){
            logger.error(e.getMessage(), e);
            throw new BusinessException(e.toString());
        }
    }

    @Override
    public int deleteAttention(TUserAttention tUserAttention) throws BusinessException {
        String where = " fromUserId=:fromUserId and toUserId=:toUserId" ;
        Map<String, Object> param = new HashMap<>();
        param.put("fromUserId", tUserAttention.getFromUserId());
        param.put("toUserId", tUserAttention.getToUserId());
        try {
            return this.getDao().delete("t_user_attention", where, param);
        } catch (SQLException e) {
            e.printStackTrace();
            logger.error(e.getMessage());
            throw new BusinessException(e.toString());
        }
    }

    @Override
    public List<TUser> queryUserList(TUserVo tUserVo) throws BusinessException {
        String sql = "select * from t_user where state='1' and (username like :key or phone like:key)";
        Map<String, Object> param = new HashMap<>();
        param.put("key", "%" + tUserVo.getKey() + "%");

        try {
            return this.getDao().selectList(TUser.class, sql, param);
        } catch (SQLException e) {
            e.printStackTrace();
            logger.error(e.getMessage());
            throw new BusinessException(e.toString());
        }
    }


    private Map<String,Object> searchParma(TUserVo tUserVo){
        if(tUserVo == null){
            return Collections.emptyMap();
        }
        String sql = "";
        HashMap<String,Object> resMap = new  HashMap<String,Object>();
        HashMap<String,Object> paramMap = new  HashMap<String,Object>();
        if(BaseUtils.isNotBlank(tUserVo.getId())){
            sql += " and ID = :getId";
            paramMap.put("getId",tUserVo.getId());
        }
        if(BaseUtils.isNotBlank(tUserVo.getPhone())){
            sql += " and phone = :phone";
            paramMap.put("phone",tUserVo.getPhone());
        }
        if(BaseUtils.isNotBlank(tUserVo.getUserName())){
            sql += " and username = :username";
            paramMap.put("username",tUserVo.getUserName());
        }
        if(BaseUtils.isNotBlank(tUserVo.getState())){
            sql += " and state = :state";
            paramMap.put("state",tUserVo.getState());
        }

        sql += " ";
        resMap.put("sql",sql);
        resMap.put("paramMap",paramMap);
        return resMap;
    }

    /**
     * 创建更新用户的信息
     * @param params 更新参数
     * @param tUserVo 用户对象
     * @return 更新参数的sql
     */
    private String createUpdateUserInfo(Map<String, Object> params, TUserVo tUserVo) {
        if(tUserVo == null){
            logger.error("user:{} not exist.");
            throw new BusinessException("用户不存在");
        }
        String sql = "";
        if(BaseUtils.isNotBlank(tUserVo.getPassword())){
            sql += ", password = :password";
            params.put("password", tUserVo.getPassword());
        }

        if(tUserVo.getLastLookAttenTime() != null) {
            sql += ", lastLookAttenTime = :lastLookAttenTime";
            params.put("lastLookAttenTime", tUserVo.getLastLookAttenTime());
        }

        if(tUserVo.getLastLookFriendTime() != null) {
            sql += ", lastLookFriendTime = :lastLookFriendTime";
            params.put("lastLookFriendTime", tUserVo.getLastLookFriendTime());
        }

        if(BaseUtils.isNotBlank(tUserVo.getUserName())){
            sql += ", userName = :userName";
            params.put("userName", tUserVo.getUserName());
        }
        if(BaseUtils.isNotBlank(tUserVo.getLikeLocation())){
            sql += ", likeLocation = :likeLocation";
            params.put("likeLocation", tUserVo.getLikeLocation());
        }
        if(BaseUtils.isNotBlank(tUserVo.getProfession())){
            sql += ", profession = :profession";
            params.put("profession", tUserVo.getProfession());
        }
        if(BaseUtils.isNotBlank(tUserVo.getPhotoUrl())){
            sql += ", photoUrl = :photoUrl";
            params.put("photoUrl", tUserVo.getPhotoUrl());
        }
        if(BaseUtils.isNotBlank(tUserVo.getSex())){
            sql += ", sex = :sex";
            params.put("sex", tUserVo.getSex());
        }
        if(BaseUtils.isNotBlank(tUserVo.getSignature())){
            sql += ", signature = :signature";
            params.put("signature", tUserVo.getSignature());
        }

        return sql.replaceFirst(",", "");
    }

    /**
     * 创建更新好友请求的信息
     * @param params 更新参数
     * @param tUserFriend 请求对象
     * @return 更新参数的sql
     */
    private String createUpdateUserFriendInfo(Map<String, Object> params, TUserFriend tUserFriend) {
        if(tUserFriend == null){
            logger.error("user:{} not exist.");
            throw new BusinessException("用户不存在");
        }
        String sql = "";
        if(BaseUtils.isNotBlank(tUserFriend.getState())){
            sql += ", state = :state";
            params.put("state", tUserFriend.getState());
        }

        return sql.replaceFirst(",", "");
    }
}


